package group6renderer;

import java.util.HashMap;


import java.awt.Color;
import java.util.HashMap;
import javax.swing.*;
import java.util.Stack;

/**
 * A class containing a HashMap of boolean variables allowing easy access to return and toggle attributes.
 * 
 * @author Joe Thomas
 * 
 */
public class State
{


    private static final boolean DEFAULT_BOLD = false;
    private static final boolean DEFAULT_ITALIC = false;
    private static final boolean DEFAULT_UNDERLINED = false;
    private static final boolean DEFAULT_WRAPPED = false;
    private static final boolean DEFAULT_TTFONT= false;
    private static final boolean DEFAULT_PRE= false;
    
    private static final boolean DEFAULT_CENTER= false;
   
    private static final boolean DEFAULT_BLOCKQUOTE= false;
    private static final boolean DEFAULT_HEADING= false;
    private static final boolean DEFAULT_DEFINITION_DATA= false; 
    private static final boolean DEFAULT_LISTINDEX= false;
    
	private static final int LEFT_SWING = SwingConstants.LEFT;
	private static final int RIGHT_SWING = SwingConstants.RIGHT;
	private static final int CENTER_SWING = SwingConstants.CENTER;
    

    
    // instance variables (fields). 
    private HashMap<String, Boolean> booleanStates;
    private Stack<Integer> alignmentStack;
    private int[] headings;
    private boolean headingTagFound=false;
    private String listIndex="";
    
    
    /**
     * A Constructor to initialise the instance variables of a new State.
     */
    public State()
    {     
        booleanStates = new HashMap<String, Boolean>();
        booleanStates.put(HTMLConstants.BOLD, DEFAULT_BOLD);
        booleanStates.put(HTMLConstants.ITALIC, DEFAULT_ITALIC);
        booleanStates.put(HTMLConstants.UNDERLINE, DEFAULT_UNDERLINED);
        booleanStates.put(HTMLConstants.WRAPPED, DEFAULT_WRAPPED);
        booleanStates.put(HTMLConstants.BLOCKQUOTE, DEFAULT_BLOCKQUOTE);
        booleanStates.put(HTMLConstants.PRE, DEFAULT_PRE);
        booleanStates.put(HTMLConstants.CENTER,DEFAULT_CENTER);
        booleanStates.put(HTMLConstants.TTFONT,DEFAULT_TTFONT);
        
        
        booleanStates.put(HTMLConstants.BLOCKQUOTE, DEFAULT_BLOCKQUOTE);
        booleanStates.put(HTMLConstants.LISTINDEX,DEFAULT_LISTINDEX);
        booleanStates.put(HTMLConstants.HEADING,DEFAULT_HEADING);
        booleanStates.put(HTMLConstants.DEFINITION_DATA,DEFAULT_DEFINITION_DATA);
        
        
        headings=new int[HTMLConstants.LEVELS_OF_HEADINGS];
        
        alignmentStack=new Stack<Integer>();
        alignmentStack.push((Integer)LEFT_SWING);
   //     alignmentStack.push((Integer)LEFT_SWING);
       

        
    }
    /**
     * A method to toggle a single boolean state. That is if the state is true, it will be made to be false and visa-versa. This is a first attempt towards making sure that 
     * a state is deactivated after the visitor has left the node relating to this state for good. It takes a string which is the key of one of the attributes in the HashMap.
     * @param key The key of the attribute that needs to be toggled.  *Range: must use one of State.BOLD, State.ITALIC, State.UNDERLINED, State.WRAPPED.
     */
    public void toggleState(String key)
    {
        boolean state = booleanStates.get(key);

        state=!state;
        booleanStates.remove(key);
        booleanStates.put(key, state);
    }
    
    /**
     * This method sets the state key to value. It should not really be called toggleState but setState
     * @param key The attribute to set
     * @param value the boolean value to set it to
     */
    public void toggleState(String key,boolean value)
    {
    	booleanStates.remove(key);
    	booleanStates.put(key, value);
    	
    	
    }
    
    /**
     * A method to return the state of a single boolean state. It takes a string which is the key of one of the attributes in the HashMap.
     * @param key The key of the attribute that needs to be toggled.  *Range: must use one of State.BOLD, State.ITALIC, State.UNDERLINED, State.WRAPPED.
     */
    public boolean getState(String key)
    {
    	
        return booleanStates.get(key);
        
    }
    
    
    public void setListIndex(String index)
    {
	
    	listIndex=index;
    }
    
    public String getListIndex()
    {
    	String listIndex=this.listIndex;
    	
    	this.listIndex="";

    	return listIndex+"  ";
    }
    
 
    /** 
     * A method to set the heading number of a piece of text.
     * @param heading the number to set the heading to.  *Range: between 1.0 and 7.7.
     */
    
    
    public void setHeading(int level)
    {
    	level--;//this is because the numbers are 1-7 but array uses 0-6
    	
    	headings[level]++;
    	for (int i=0;i<HTMLConstants.LEVELS_OF_HEADINGS;i++)
    	{
    		if (i>level)
    			headings[i]=0;
    		else
    			if	((i<level) && (headings[i]==0)) headings[i]++; 
    		
    	}
    	
    	
    	
    	headingTagFound=true;
    }
    
    public String getHeading()
    {
    	
    	String heading="";
    	
    	if (headingTagFound)
    	{
    		for (int i=0;i<HTMLConstants.LEVELS_OF_HEADINGS;i++)
    		{
    			
    			if( headings[i]==0) break;
    			heading=heading+headings[i]+".";
    			
    			
    		}
    		headingTagFound=false;
    		return heading+"  ";
    	}
    	return heading;
    }
  

    
}